
import { reactive } from 'vue'
import SparkMD5 from 'spark-md5'
import axios from 'axios'
export function uploadFile() {

  let upFileState = reactive({
    fileList: []
  })
  /**
   * 大文件上传
   * 1 将大文件惊醒分段3M，发送到服务器携带一个标志（时间戳）用于标识一个完整的文件
   * 2 服务器保存各段文件
   * 3 浏览器端在所有文件上传成功之后，发送一个合并文件的请求
   * 4 服务端根据文件标识，类型，按分片顺序合并文件
   * 5 删除分片文件
   * 6 web worker 多线程
   * 7 切片核心是利用Blob.prototype.slice 方法 利用web workwe结合spark-md5去计算文件的hash值
   * 
   */
  const onUploadFile = async (File) => {
    const chunkSize = 1024 * 1024 * 1024 // 分片大小
    const file = File.raw // 文件
    const fileSize = File.size // 文件大小
    let chunkCount = Math.ceil(fileSize / chunkSize) // 分片数量

    if (chunkSize > fileSize) {
      chunkCount = 1 // 文件过小就一片
    }

    const fileMd5 = await getFileMd5(file, chunkCount, chunkSize) // 文件md5
    // uploadChunkFile(chunkCount, fileMd5)
    let promiseList = []
    const instance = axios.create({
      baseURL: '',
      timeout: 1000,
      headers: { 'X-Custom-Header': 'foobar' }
    })
    for (let i = 0; i < chunkCount; i++) {
      const start = i * chunkSize // 分片开始
      const end = Math.min(fileSize, start + chunkSize) // 分片结束
      const _chunkFile = File.raw.slice(start, end) // 分片文件
      const formdata = new FormData()
      formdata.append('chunkNumber', i.toString())
      formdata.append('chunkSize', _chunkFile.size)
      formdata.append('audio_file', _chunkFile)
      formdata.append('fileName', File.name)
      formdata.append('fileSign', fileMd5)
      formdata.append('totalChunks', chunkCount.toString())
      formdata.append('totalChunkSize', fileSize)


      // 以下是检查是否已上传文件，实现文件秒传
      // const params = { chunkNumber: i, fileSign: fileMd5 }
      // const { data } = await checkChunkFile(params) // 检查分片文件是否上传
  
      console.log("开始上传第" + i + "个分片")
      // await uploadChunkFile(formdata) // 上传分片
      let iQ = instance.request({
        url: '/asr?encode=true&task=transcribe&output=json',
        method: 'post', //
        headers: {'Accept':'application/json','Content-Type':'multipart/form-data' },
        data: {'audio file':formdata}
      })
      promiseList.push(iQ)
    }
    Promise.all(promiseList).then(() => {
      const mergeData = { fileName: File.name, fileSign: fileMd5 }
      mergeFile(mergeData) // 合并分片
    })


  }
  const getFileMd5 = (file, chunkCount, chunkSize) => {
    return new Promise((resolve, reject) => {
      const blobSlice = File.prototype.slice
      const spark = new SparkMD5.ArrayBuffer()
      const fileReader = new FileReader()
      let currentChunk = 0

      fileReader.onload = e => {
        spark.append(e.target?.result)
        currentChunk++
        if (currentChunk < chunkCount) {
          loadNext()
        } else {
          resolve(spark.end())
        }
      }

      fileReader.onerror = e => {
        reject(e)
      }

      function loadNext() {
        const start = currentChunk * chunkSize
        let end = start + chunkSize
        if (end > file.size) {
          end = file.size
        }
        fileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
      }

      loadNext()
    })
  }
  const mergeFile = async (mergeData) => {
    await fetch('http://localhost:3000/merge', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(mergeData)
    })
  }
  function uploadChunkFile(chunkList, md5) {
    const promiseList = chunkList.map((chunk, index) => {
      // const formData = new FormData()
      // formData.append('file', chunk)
      // formData.append('index', index)
      // formData.append('md5', md5)

      const start = i * chunkSize // 分片开始
      const end = Math.min(fileSize, start + chunkSize) // 分片结束
      const _chunkFile = File.raw.slice(start, end) // 分片文件

      const formdata = new FormData()
      formdata.append('chunkNumber', i.toString())
      formdata.append('chunkSize', _chunkFile.size)
      formdata.append('file', _chunkFile)
      formdata.append('fileName', File.name)
      formdata.append('fileSign', fileMd5)
      formdata.append('totalChunks', chunkCount.toString())
      formdata.append('totalChunkSize', fileSize)

      const instance = axios.create({
        baseURL: 'http://10.0.116.193:9000/',
        timeout: 1000,
        headers: { 'X-Custom-Header': 'foobar' }
      })
      instance.request({
        url: '/asr',
        method: 'post', //
        headers: { 'Content-Type': 'multipart/form-data' },
        data: {
          encode: 'true',
          task: 'transcribe',
          output: 'json'
        },
        body: formData
      }).then(() => {

      })

      // return fetch('/rl-baisha/sxyd/attach/upload', {
      //   method: 'POST',
      //   body: formData
      // }).then(response => response.json())
    })

    return Promise.all(promiseList)
  }
  function mergeChunks(md5, mergeUrl) {
    return fetch(mergeUrl, {
      method: 'POST',
      body: JSON.stringify({ md5 }),
      headers: {
        'Content-Type': 'application/json'
      }
    }).then(response => response.json())
  }
  return { onUploadFile, upFileState }

}